home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- vlan.c - Routines to help talk to VLAN network.
-
- Tim Heidmann
- Created March 1, 1993
- Last Edit Oct 22, 1993
- Add vlan_Send (send-only) and vlan_Recv (poll for ascii/bin messages).
- Add minimal timestamping.
- */
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <termio.h>
- #include "vlan.h"
-
- #define VLAN_CMD_NAP 5
- #define VLAN_CMD_TIMEOUT 15
-
- int vlan_sending = TRUE;
- int vlan_receiving = TRUE;
- int vlan_debug = FALSE;
- int vlan_errno;
- int vlan_f;
- char vlan_port[256] = "/dev/ttyd2";
- char vlan_neatTC_buf[64];
- int vlan_timeout = -1;
- struct timeval vlan_msg_stamp;
-
- int vlan_SetTimeout(int, int);
-
- int
- vlan_InitPort(char *vlan_port)
- {
- struct termio term;
-
- if (vlan_sending) {
- if ((vlan_f = open(vlan_port, O_RDWR)) < 0) {
- vlan_errno = VLAN_CANT_OPEN;
- return -1;
- }
- }
-
- if (ioctl(vlan_f, TCGETA, &term) == -1) {
- vlan_errno = VLAN_TCGETA;
- return -1;
- }
-
- /* change the modes */
- term.c_iflag = IGNBRK;
- term.c_oflag = 0;
- term.c_lflag = 0;
- term.c_cflag = B9600 | CS8 | CREAD;
- term.c_cc[VMIN] = 1;
- term.c_cc[VTIME] = 0;
-
- if (ioctl(vlan_f, TCSETA, &term) == -1) {
- vlan_errno = VLAN_TCSETA;
- return -1;
- }
-
- return 0;
- }
-
- char *
- vlan_SendCmd(char c[])
- {
- int iChar, timedOut;
- char vlan_command[256];
- static char vlan_response[256];
- char *resp;
-
- /* Flush the input buffer */
- if (vlan_receiving) {
- /* Set up for immediate return */
- if (vlan_SetTimeout(0, 0) < 0) return NULL;
- while (read(vlan_f,resp,1) > 0) ;
- }
-
- /* Send the desired command */
- if (vlan_debug)
- fprintf(stdout, "--IRIS: %s\n", c);
- if (vlan_sending) {
- for (iChar = 0; c[iChar] != '\0'; iChar++)
- vlan_command[iChar] = c[iChar];
- vlan_command[iChar++] = '\r';
- write(vlan_f, vlan_command, iChar);
- /*
- sginap(VLAN_CMD_NAP);
- */
- }
-
- /* Read the VLAN response */
- if (vlan_receiving)
- /* Set up for max allowed response time */
- if (vlan_SetTimeout(0, VLAN_CMD_TIMEOUT) < 0) return NULL;
- timedOut = FALSE;
- for (resp = vlan_response; ; resp++) {
- if (read(vlan_f,resp,1) <= 0) {
- /* Timeout */
- *resp = '\0';
- timedOut = TRUE;
- break;
- }
- if (*resp == '\r') {
- /* Carriage return signals end of response */
- *resp = '\0';
- break;
- }
- }
-
- if (vlan_debug)
- fprintf(stdout, " VLAN: %s%s\n",
- vlan_response, timedOut ? "*** TIMEOUT ***" : "");
-
- return timedOut ? NULL : vlan_response;
- }
-
- int
- vlan_Coincidence(int ds, char *ch) {
- int val;
- char blah[1];
- fd_set fdset;
- struct timeval timeout;
-
- if (!vlan_receiving)
- return 0;
-
- /***
- FD_ZERO(&fdset);
- FD_SET(vlan_f, &fdset);
- timeout.tv_sec = 30;
- timeout.tv_usec = 0;
- val = select(1, fdset, 0, 0, 0);
- printf("val returned from select = %d\n", val);
- ***/
-
- /* Set maximum wait time (1/10th secs) */
- if (vlan_SetTimeout(1, ds) < 0) return -1;
-
- /* Wait here for a character */
- val = read(vlan_f, blah, 1);
- if (val < 0) {
- vlan_errno = VLAN_READ_COINCIDENCE;
- return -1;
- }
- else if (val == 0) {
- vlan_errno = VLAN_TIMEOUT;
- return -1;
- }
- else
- {
- *ch = blah[0];
- return 0;
- }
- }
-
-
- int
- vlan_SetTimeout(int min, int ds)
- {
- struct termio term;
-
- if (!vlan_receiving) return 0;
-
- if (ds < 0 || ds > 255) {
- vlan_errno = VLAN_BAD_TIMEOUT;
- return -1;
- }
-
- if (ioctl(vlan_f, TCGETA, &term) == -1) {
- vlan_errno = VLAN_TCGETA;
- return -1;
- }
-
- /* change the MIN/TIME values
- * (assume still setup for non-canonic processing)
- */
- term.c_cc[VMIN] = min;
- term.c_cc[VTIME] = vlan_timeout = ds;
-
- if (ioctl(vlan_f, TCSETA, &term) == -1) {
- vlan_errno = VLAN_TCSETA;
- return -1;
- }
-
- return 0;
- }
-
-
-
- #define FPS 30
- #define FPM 1800
- #define FPH 108000
- static char vlan_tcBuf[32];
-
- char *vlan_FtoTC(int iFrame) {
- int h, m, s;
-
- if (iFrame < 0)
- vlan_tcBuf[0] = '\0';
-
- else {
- h = iFrame / FPH;
- iFrame -= h * FPH;
- m = iFrame / FPM;
- iFrame -= m * FPM;
- s = iFrame / FPS;
- iFrame -= s * FPS;
- sprintf(vlan_tcBuf, "%02d:%02d:%02d:%02d", h, m, s, iFrame);
- }
-
- return vlan_tcBuf;
- }
-
- int vlan_TCtoF(char *tc) {
- int h, m, s, f;
- char *neat_tc;
-
- neat_tc = vlan_neatTC(tc);
- if (sscanf(neat_tc, "%2d%2d%2d%2d", &h, &m, &s, &f) != 4) {
- vlan_errno = VLAN_PARSE_TIMECODE;
- return -1;
- }
-
- return (h*FPH + m*FPM + s*FPS + f);
- }
-
- char *vlan_neatTC(char *tc) {
- char *np, tmpBuf[64];
- int bufLen;
-
- /* Remove all but numerics. */
- for (np = tmpBuf; *tc != '\0'; tc++)
- if (*tc >= '0' && *tc <= '9') {
- *np = *tc;
- np++;
- }
- *np = '\0';
-
- /* Return empty string if no numerics at all.
- * Otherwise, truncate to 8 characters (hhmmssff) or pad with 0's
- */
- if ((bufLen = strlen(tmpBuf)) <= 0)
- vlan_neatTC_buf[0] = '\0';
- else if (bufLen > 8)
- strcpy(vlan_neatTC_buf, tmpBuf + bufLen - 8);
- else {
- strcpy(vlan_neatTC_buf, "00000000");
- strcpy(vlan_neatTC_buf + 8 - bufLen, tmpBuf);
- }
-
- return vlan_neatTC_buf;
- }
-
-
- void
- vlan_perror(char *str) {
- char buf[256];
-
- switch (vlan_errno) {
- case VLAN_CANT_OPEN:
- sprintf(buf, "%s: Open VLAN port", str);
- perror(buf);
- break;
- case VLAN_TCGETA:
- sprintf(buf, "%s: Get VLAN serial attributes", str);
- perror(buf);
- break;
- case VLAN_TCSETA:
- sprintf(buf, "%s: Set VLAN serial attributes", str);
- perror(buf);
- break;
- case VLAN_PARSE_TIMECODE:
- fprintf(stderr, "%s: Can't parse VLAN timecode string\n", str);
- break;
- case VLAN_BAD_TIMEOUT:
- fprintf(stderr, "%s: Bad VLAN timeout specification\n", str);
- break;
- case VLAN_READ_COINCIDENCE:
- sprintf(buf, "%s: Read VLAN coincidence character", str);
- perror(buf);
- break;
- case VLAN_TIMEOUT:
- fprintf(stderr, "%s: VLAN timeout\n", str);
- break;
- case VLAN_CAPTURE_DEAD:
- fprintf(stderr, "%s: VLAN continuous capture timeout\n", str);
- break;
- default:
- fprintf(stderr, "%s: VLAN error\n", str);
- break;
- }
- }
-
-
-
- void
- vlan_Send(char c[])
- {
- int iChar, timedOut;
- char vlan_command[256];
- static char vlan_response[256];
- char *resp;
-
- /* Flush the input buffer */
- if (vlan_receiving) {
- /* Set up for immediate return */
- vlan_SetTimeout(0, 0);
- while (read(vlan_f,resp,1) > 0) ;
- }
-
- /* Send the desired command */
- if (vlan_debug)
- fprintf(stdout, "--IRIS: %s\n", c);
- if (vlan_sending) {
- for (iChar = 0; c[iChar] != '\0'; iChar++)
- vlan_command[iChar] = c[iChar];
- vlan_command[iChar++] = '\r';
- write(vlan_f, vlan_command, iChar);
- }
- }
-
-
- #define VLAN_RECVBUF_LEN 512
- unsigned char vlan_recvBuf[VLAN_RECVBUF_LEN];
- int vlan_recvBuf_start = 0, vlan_recvBuf_end = 0;
- int charCnt = 0;
- enum {vlan_recv_start, vlan_recv_ascii, vlan_recv_esc, vlan_recv_flush}
- vlan_recv_state;
-
- int
- vlan_Recv(char **c, vlan_esc_struct **e, struct timeval *ts) {
- int this_start, i, n, j;
-
- if (vlan_SetTimeout(0, 0) < 0) return -1;
- if ((n = read(vlan_f, vlan_recvBuf + vlan_recvBuf_end,
- VLAN_RECVBUF_LEN - vlan_recvBuf_end)) < 0) return -1;
- charCnt += n;
- this_start = vlan_recvBuf_end;
- vlan_recvBuf_end += n;
-
- for (;;)
- switch (vlan_recv_state) {
- case vlan_recv_start:
- /* Move buffer contents to head of buffer; check for ASCII/bin */
- if (vlan_recvBuf_start > 0) {
- for (i = 0; i < vlan_recvBuf_end - vlan_recvBuf_start; i++)
- vlan_recvBuf[i] = vlan_recvBuf[i+vlan_recvBuf_start];
- vlan_recvBuf_end -= vlan_recvBuf_start;
- vlan_recvBuf_start = 0;
- }
-
- if (vlan_recvBuf_end == vlan_recvBuf_start)
- /* Nothing read yet */
- return 0;
-
- else {
- gettimeofday(&vlan_msg_stamp, NULL);
- vlan_msg_stamp.tv_usec -= 1000 * n;
- this_start = vlan_recv_start;
- if (vlan_recvBuf[vlan_recvBuf_start] == 0x1b)
- /* Escape message */
- vlan_recv_state = vlan_recv_esc;
- else if ((vlan_recvBuf[vlan_recvBuf_start] >= 32 &&
- vlan_recvBuf[vlan_recvBuf_start] <= 127) ||
- vlan_recvBuf[vlan_recvBuf_start] == '\r')
- /* Ascii */
- vlan_recv_state = vlan_recv_ascii;
- else
- /* Random binary stuff - flush it */
- vlan_recv_state = vlan_recv_flush;
- }
- break;
-
-
- case vlan_recv_ascii:
- for (i=this_start; i<vlan_recvBuf_end; i++) {
- if (vlan_recvBuf[i] == '\r') {
- /* End of ascii message */
- *c = vlan_recvBuf + vlan_recvBuf_start;
- vlan_recvBuf[i] = '\0';
- if (ts != NULL) *ts = vlan_msg_stamp;
- if (vlan_debug)
- fprintf(stdout, "ASCII: %s (%d bytes remain)\n", *c, vlan_recvBuf_end-i-1);
- vlan_recvBuf_start = i + 1;
- vlan_recv_state = vlan_recv_start;
- break;
-
- } else if (vlan_recvBuf[vlan_recvBuf_start] < 32 &&
- vlan_recvBuf[vlan_recvBuf_start] > 127) {
- /* Non-ascii value detected in message */
- vlan_recv_state = vlan_recv_flush;
- break;
- }
- }
- if (vlan_recv_state == vlan_recv_start) return 1;
- else if (vlan_recv_state == vlan_recv_flush) break;
- else
- /*
- return 0;
- */
- if (vlan_recvBuf_start == vlan_recvBuf_end) {
- return 0;
- } else {
- return 3;
- }
-
-
- case vlan_recv_esc:
- for (i=this_start; i<vlan_recvBuf_end; i++) {
- if (vlan_recvBuf[i] == '\r') {
- /* End of escape message */
- *e = (vlan_esc_struct *) vlan_recvBuf + vlan_recvBuf_start;
- if (vlan_debug) {
- fprintf(stdout, "ESC: ");
- for (j = vlan_recvBuf_start; j <= i; j++) {
- if ((j % 16) == 15) fprintf(stdout,"\n ");
- fprintf(stdout, "0x%02x ", vlan_recvBuf[j]);
- }
- fprintf(stdout, "\n");
- }
- if (ts != NULL) *ts = vlan_msg_stamp;
- vlan_recvBuf_start = i + 1;
- vlan_recv_state = vlan_recv_start;
- break;
- }
- }
- if (vlan_recv_state == vlan_recv_start) return 2;
- else
- /*
- return 0;
- */
- if (vlan_recvBuf_start == vlan_recvBuf_end) {
- return 0;
- } else {
- return 3;
- }
-
-
- case vlan_recv_flush:
- /* Look for a CR */
- for (i = vlan_recvBuf_start; i < vlan_recvBuf_end; i++)
- if (vlan_recvBuf[i] == '\r') {
- vlan_recvBuf_start = i + 1;
- vlan_recv_state = vlan_recv_start;
- break;
- }
-
- if (vlan_recv_state == vlan_recv_flush) {
- /* No CR found in this batch. Return */
- vlan_recvBuf_start = vlan_recvBuf_end = 0;
- return 0;
- }
- break;
- }
- }
-
-